/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

#include "sle_lite_tool_ssap_client.h"

void OnSleTFindStructureCb(uint8_t clientId, uint16_t connectId
        , const ClientFindServiceRes *service, SleErrorCode errCode)
{
    printf("[SleSsapClientTestTool] OnSleTFindStructureCb: uuid(%s) (%d,%d) [%d:%d] errCode(%hhu)\r\n"
        , service->uuid.uuid, connectId, clientId, service->startHandle, service->endHandle, errCode);
}

void OnSleTFindPropertyCb(uint8_t clientId, uint16_t connectId
        , const ClientFindPropertyRes *property, SleErrorCode errCode)
{
    printf("[SleSsapClientTestTool] OnSleTFindPropertyCb: uuid(%s) (%d,%d) opInd(%u) despsType(%hhu) errCode(%hhu)\r\n"
        , property->uuid.uuid, connectId, clientId, property->operateIndication, property->descriptorsType, errCode);
}

void OnSleTReadCfmCb(uint8_t clientId, uint16_t connectId
        , const ClientHandleValue *readData, SleErrorCode errCode)
{
    printf("[SleSsapClientTestTool] OnSleTReadCfmCb:  (%d,%d) handle(%d) type(%s) errCode(%hhu) value(%s)\r\n"
        , connectId, clientId, readData->handle, SleSsapPropertyTypeStr(readData->type), errCode, readData->data);
}

void OnSleTWriteCfmCb(uint8_t clientId, uint16_t connectId
        , const ClientWriteRes *writeResult, SleErrorCode errCode)
{
//    printf("[SleSsapClientTestTool] OnSleTWriteCfmCb: (%d,%d) handle(%d) type(%s) errCode(%hhu)\r\n"
//        , connectId, clientId, writeResult->handle, SleSsapPropertyTypeStr(writeResult->type), errCode);
}

void OnSleTExchangeInfoCb(uint8_t clientId, uint16_t connectId
        , const SsapMtuInfo *exchangeInfo, SleErrorCode errCode)
{
    printf("[SleSsapClientTestTool] OnSleTExchangeInfoCb: (%d,%d) mtuSize(%u) errCode(%hhu)\r\n"
        , connectId, clientId, exchangeInfo->mtuSize, errCode);
}

void OnSleTNotificatedCb(uint8_t clientId, uint16_t connectId
        , const ClientHandleValue *data, SleErrorCode errCode)
{
//    printf("[SleSsapClientTestTool] OnSleTNotificatedCb: (%d,%d) handle(%d) type(%s) errCode(%hhu) value(%s)\r\n"
//        , connectId, clientId, data->handle, SleSsapPropertyTypeStr(data->type), errCode, data->data);
}

void OnSleTIndicatedCb(uint8_t clientId, uint16_t connectId
        , const ClientHandleValue *data, SleErrorCode errCode)
{
    printf("[SleSsapClientTestTool] OnSleTIndicatedCb (%d,%d) handle(%d) type(%s) errCode(%hhu) value(%s)\r\n"
        , connectId, clientId, data->handle, SleSsapPropertyTypeStr(data->type), errCode, data->data);
}

static uint8_t g_clientId = 0xFF;

uint8_t GetSleToolSsapClientId(void)
{
    return g_clientId;
}

void TAddSspaClient(void)
{
    if (g_clientId != 0xFF) {
        printf("[SleSsapClientTestTool] AddSspaClient already add success.\r\n");
        return;
    }
    SleUuid appUuid;
    memcpy(appUuid.uuid, "SleToolSsapc", strlen("SleToolSsapc"));
    appUuid.len = strlen("SleToolSsapc");
    SleErrorCode ret = AddSspaClient(&appUuid, &g_clientId);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapClientTestTool] AddSspaClient failed(%hhu)\r\n", ret);
        return;
    }
    SLE_TEST_TOOL_LOG("[SleSsapClientTestTool] AddSspaClient success(%d)", g_clientId);
}

void TRemoveClient(void)
{
    SleErrorCode ret = RemoveClient(g_clientId);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapClientTestTool] RemoveClient failed(%hhu)\r\n", ret);
        return;
    }
    SLE_TEST_TOOL_LOG("[SleSsapClientTestTool] RemoveClient success(%d)", g_clientId);
    g_clientId = 0xFF;
}

void TFindSsapStructure(void)
{
    uint16_t connectId = (uint16_t)SleGetInputNumber("please input connectId: ");
    ClientFindStructure paramFind = {0};
    paramFind.findType = (SsapFindType )SleGetInputNumber("please input findType: ");
    paramFind.startHandle = (uint16_t)SleGetInputNumber("please input startHandle: ");
    paramFind.endHandle = (uint16_t)SleGetInputNumber("please input endHandle: ");
    SleErrorCode ret = FindSsapStructure(g_clientId, connectId, &paramFind);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapClientTestTool] FindSsapStructure failed(%hhu)\r\n", ret);
        return;
    }
}

void TSendReadReqByUuid(void)
{
    uint16_t connectId = (uint16_t)SleGetInputNumber("please input connectId: ");
    ClientReadReqByUUID paramRead;
    paramRead.findType = (SsapFindType )SleGetInputNumber("please input findType: ");
    paramRead.startHandle = (uint16_t)SleGetInputNumber("please input startHandle: ");
    paramRead.endHandle = (uint16_t)SleGetInputNumber("please input endHandle: ");
    char temp[UUID_LEN + 1];
    SleGetInputString("please input uuid: ", temp, UUID_LEN + 1);
    memcpy(paramRead.uuid.uuid, temp, strlen(temp));
    paramRead.uuid.len = strlen(temp);
    SleErrorCode ret = SendReadReqByUuid(g_clientId, connectId, &paramRead);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapClientTestTool] SendReadReqByUuid failed(%hhu)\r\n", ret);
        return;
    }
}

void TSendReadReq(void)
{
    uint16_t connectId = (uint16_t)SleGetInputNumber("please input connectId: ");
    uint16_t handle = (uint16_t)SleGetInputNumber("please input handle: ");
    SleSsapPropertyType propertyTpye = (SleSsapPropertyType )SleGetInputNumber("please input propertyTpye: ");
    SleErrorCode ret = SendReadReq(g_clientId, connectId, handle, propertyTpye);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapClientTestTool] SendReadReq failed(%hhu)\r\n", ret);
        return;
    }
}

void TSendWriteReq(void)
{
    uint16_t connectId = (uint16_t)SleGetInputNumber("please input connectId: ");
    ClientWriteParam paramWrite;
    paramWrite.handle = (uint16_t)SleGetInputNumber("please input handle: ");
    paramWrite.type = (SleSsapPropertyType )SleGetInputNumber("please input propertyTpye: ");
    char data[257];
    SleGetInputString("Please input data:", data, 257);
    paramWrite.dataLength = strlen(data);
    paramWrite.data = (uint8_t*)malloc(paramWrite.dataLength * sizeof(uint8_t));
    memcpy(paramWrite.data, data, strlen(data));
    SleErrorCode ret = SendWriteReq(g_clientId, connectId, &paramWrite);
    free(paramWrite.data);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapClientTestTool] SendWriteReq failed(%hhu)\r\n", ret);
        return;
    }
}

void TSendWriteCmd(void)
{
    uint16_t connectId = (uint16_t)SleGetInputNumber("please input connectId: ");
    ClientWriteParam paramWrite;
    paramWrite.handle = (uint16_t)SleGetInputNumber("please input handle: ");
    paramWrite.type = (SleSsapPropertyType )SleGetInputNumber("please input propertyTpye: ");
    int dataLen = SleGetInputNumber("please input data size: ");
    char *data = (char *)malloc((dataLen + 1)* sizeof(char));
    SleGetInputString("Please input data:", data, (dataLen + 1));
    paramWrite.dataLength = strlen(data);
    paramWrite.data = (uint8_t*)malloc(paramWrite.dataLength * sizeof(uint8_t));
    memcpy(paramWrite.data, data, strlen(data));
    SleErrorCode ret = SendWriteCmd(g_clientId, connectId, &paramWrite);
    free(paramWrite.data);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapClientTestTool] SendWriteCmd failed(%hhu)\r\n", ret);
        return;
    }
}

void TSendExchangeInfoReq(void)
{
    uint16_t connectId = (uint16_t)SleGetInputNumber("please input connectId: ");
    SsapMtuInfo paramExchange;
    paramExchange.mtuSize = (uint32_t)SleGetInputNumber("please input mtuSize: ");
    SleErrorCode ret = SendExchangeInfoReq(g_clientId, connectId, &paramExchange);
    if(ret != SLE_NO_ERROR) {
        printf("[SleSsapClientTestTool] SendExchangeInfoReq failed(%hhu)\r\n", ret);
        return;
    }
}

void SleSsapClientToolHalper(void)
{
    printf("***SleSsapClientTool Command List****\r\n");
    for (uint16_t i = 0; i < g_ssapClientCmdNum; i++) {
        printf("*     %02d - %-20s     *\r\n", i, g_ssapClientCmdList[i].desc);
    }
    printf("*************************************\r\n");
}

void SleSsapClientToolCmdHandler(int argc, char **argv)
{
    printf("SleSsapClientToolCmdHandler in\r\n");
    //试配uart接口的调用方式
    SleResetEnv();
    //从函数名字之后开始处理参数列表
    SleSetBufEnv(argc, argv, 1);
    int index = SleGetInputNumber("Please input cmd index:\r\n");
    if(index < g_ssapClientCmdNum) {
        printf("cmd: %d\r\n", index);
        printf("Execute: %s\r\n", g_ssapClientCmdList[index].desc);
        g_ssapClientCmdList[index].func();
    }
    if(index != 0) g_ssapClientCmdList[0].func();
}

#ifdef __cplusplus
}
#endif // __cplusplus
